package com.tongfutele.servlet;

import com.tongfutele.op.OPFlag;
import com.tongfutele.op.PdAttr;
import com.tongfutele.op.RespCode;
import com.tongfutele.utils.BNetUtils;
import com.tongfutele.utils.LogUtil;
import com.tongfutele.utils.MessageUtil;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.ws.soap.Addressing;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.function.ObjDoubleConsumer;

/**
 * This servlet for processing customer orders for bnet.
 */
public class TyServlet extends HttpServlet {

    /**
     * api interface
     */
    public static final String ACCESS_CLIENT = "/client";
    public static final String ACCESS_USER = "/user";

    /**
     * servlet base path
     */
    private static String servletPath = "";

    /**
     * save a temp opFlag
     */
    private String opTypeCode = "0";

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        config.getServletContext().getRealPath("/");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //设置编码
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");

        servletPath = req.getServletPath();

        processingRequest(req, resp);
    }

    /**
     * processing bnet production change request.
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    private void processingRequest(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String StreamingNo = req.getParameter("streamingno");
        String rand = req.getParameter("rand");
        String encode = req.getParameter("encode");

        PrintWriter writer = resp.getWriter();

        if (StreamingNo == null || rand == null || encode == null) {
            writer.write("invalid param");
            writer.close();
            return;
        }

        //http://localhost:8080/client?streamingno=72401&rand=1234&encode=12312838134

//        String openInfo = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
//                "<Package>\n" +
//                "  <StreamingNo>747083</StreamingNo>\n" +
//                "  <OPFlag>0202</OPFlag>\n" +
//                "  <ProductID>52219</ProductID>\n" +
//                "  <OfferID/>\n" +
//                "  <BizID>5710JLY00752343</BizID>\n" +
//                "  <CustID>5710JLY00752343</CustID>\n" +
//                "  <AccountInfo>\n" +
//                "    <UserID>13336002101@5710JLY00752343</UserID>\n" +
//                "    <NewUserID/>\n" +
//                "    <AccType>3</AccType>\n" +
//                "    <AccName>13336002101</AccName>\n" +
//                "  </AccountInfo>\n" +
//                "  <Summary>用户变更产品</Summary>\n" +
//                "</Package>";

//        String openInfo = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
//                "<Package>\n" +
//                "  <StreamingNo>747083</StreamingNo>\n" +
//                "  <OPFlag>0101</OPFlag>\n" +
//                "  <ProductID>52219</ProductID>\n" +
//                "  <SIID>11078</SIID>\n" +
//                "  <OfferID/>\n" +
//                "  <BizID>5710JLY00752343</BizID>\n" +
//                "  <AreaCode>57102</AreaCode>\n" +
//                "  <CustID>5710JLY00752343</CustID>\n" +
//                "  <CustAccount>aptest</CustAccount>\n" +
//                "  <CustName>固网云化PF测试</CustName>\n" +
//                "  <Summary>客户开通产品</Summary>\n" +
//                "</Package>";

        //获取客户产品变更数据
        String openInfo = BNetUtils.getPortalRequest(rand, StreamingNo);

        //统一加密交易数据
        String encodeOpenInfo = BNetUtils.getEncodeString(openInfo);

        //校验交易数据
        if (encode.equals(encodeOpenInfo)) {
            try {
                if (openInfo.isEmpty()) {
                    writer.write("invalid openInfo:null");
                    writer.close();
                    return;
                }

                Map<String, String> openMap = MessageUtil.xml2map(openInfo, 0);
                String streamingNo = openMap.get(PdAttr.KEY_StreamingNo);
                String opFlag = OPFlag.USER_QUERY;
                String SIID = PdAttr.SIID;
                String TimeStamp = String.valueOf(new Date().getTime());
                String ProductID = PdAttr.ProductID;
                String OfferID = openMap.get(PdAttr.KEY_OfferID);
                String Password = BNetUtils.getEncodeString("123456");
                String CustID = openMap.get(PdAttr.KEY_CustID);
                String CustAccount = openMap.get(PdAttr.KEY_CustAccount);
                String UserID = openMap.get(PdAttr.KEY_UserID);
                String BizID = openMap.get(PdAttr.KEY_BizID);
                String AreaCode = openMap.get(PdAttr.KEY_AreaCode);
                String Summary = "用户信息查询";

                opTypeCode = openMap.get(PdAttr.KEY_OPFlag);

                //校验成功后立即发起查询
                String reqXml = "";

                switch (servletPath) {
                    case ACCESS_CLIENT:
                        opFlag = OPFlag.CLIENT_QUERY;
                        Summary = "客户信息查询";
                        reqXml = MessageUtil.initClientQueryInfoXml(streamingNo, opFlag, SIID, TimeStamp, ProductID, OfferID, Password, CustID, CustAccount, UserID, Summary, BizID, AreaCode);
                        break;
                    case ACCESS_USER:
                        reqXml = MessageUtil.initUsrQueryInfoXml(streamingNo, opFlag, SIID, TimeStamp, ProductID, OfferID, Password, CustID, CustAccount, UserID, Summary);
                        break;
                    default:
                        break;
                }

                String userDataInfo = BNetUtils.getPortalResult(reqXml);
                //收到查询结果做本地处理将本地处理结果返回给Bnet
                Map<String, String> userDataMap = MessageUtil.xml2map(userDataInfo);

                String sNode = userDataMap.get(PdAttr.KEY_StreamingNo);
                String respCode = userDataMap.get(PdAttr.KEY_ReturnStatus);
//                String respCode = saveUserInfo(userDataInfo)? RespCode.RESP_CODE_00000 : RespCode.RESP_CODE_00205;

                //上报处理结果
                String reportXml = MessageUtil.initRespPdInfoXml(openMap.get(PdAttr.KEY_StreamingNo),
                        openMap.get(PdAttr.KEY_OPFlag),
                        respCode,
                        openMap.get(PdAttr.KEY_Summary));
                BNetUtils.getPortalResult(reportXml);

                if (!respCode.equals(RespCode.RESP_CODE_00000)) {
                    //领航处理失败,本地回滚客户变更数据
                    LogUtil.i("respCode:" + respCode);
                } else {
                    String savestr = saveUserInfo(userDataInfo, sNode, opTypeCode) ? "存储成功" : "存储失败";
                    LogUtil.i("savestr:" + savestr);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            writer.write("invalid encode:" + encodeOpenInfo);
            LogUtil.i("invalid encode:" + encodeOpenInfo);
        }
        writer.close();
    }

    /**
     * 存储交易数据
     *
     * @param tradeInfo     数据
     * @param streamingNode 流水号
     * @param opTypeCode    变更类型
     * @return
     */
    private boolean saveUserInfo(String tradeInfo, String streamingNode, String opTypeCode) {
        boolean rst = true;

        //领航处理成功,存储数据
        String type = "modify";
        if (OPFlag.CLIENT_ACTIVATE.equals(opTypeCode)) {
            type = "trade";
        }

        String opTypeStr = opTypeCode;
        switch (opTypeCode) {
            case OPFlag.CLIENT_ACTIVATE:
                opTypeStr = "client_activate";
                break;
            case OPFlag.CLIENT_UNSUBSCRIBE:
                opTypeStr = "client_unsubscribe";
                break;
            case OPFlag.CLIENT_CHANGE:
                opTypeStr = "client_change";
                break;
            case OPFlag.USER_ACTIVATE:
                opTypeStr = "user_activate";
                break;
            case OPFlag.USER_QUERY:
                opTypeStr = "user_query";
                break;
            case OPFlag.USER_CHANGE:
                opTypeStr = "user_change";
                break;
            case OPFlag.USER_UNSUBSCRIBE:
                opTypeStr = "user_unsubscribe";
                break;
        }

        //交易记录目录
        String tradeDirPath = getServletContext().getRealPath("/") + "trade_record";

        SimpleDateFormat myFmt = new SimpleDateFormat("yyyy-MM-dd");
        String timeTap = myFmt.format(new Date());
        String dot = ".";

        //交易文件格式：2017-5-5.streamingNode.trade.xml
        //变更文件格式：2017-5-6.streamingNode.modify.xml
        StringBuffer buffer = new StringBuffer();
        buffer.append(tradeDirPath)
                .append(File.separator)
                .append(timeTap)
                .append(dot)
                .append(streamingNode)
                .append(dot)
                .append(type)
                .append(dot)
                .append(opTypeStr)
                .append(dot)
                .append("xml");
        String tradeInfoPath = buffer.toString();

        LogUtil.i("tradeDirPath:" + tradeDirPath);
        LogUtil.i("tradeInfoPath:" + tradeInfoPath);

        try {
            File dir = new File(tradeDirPath);
            if (!dir.exists()) {
                dir.mkdir();
            }
            File file = new File(tradeInfoPath);
            if (!file.exists()) {
                file.createNewFile();
            }
            if ("modify".equals(type)) {
                String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
                tradeInfo = "<!--" + now + "-->\n" + tradeInfo + "\n";
            }
            FileUtils.writeStringToFile(file, tradeInfo, "utf-8", true);
        } catch (IOException e) {
            rst = false;
            e.printStackTrace();
        }
        return rst;
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
    }
}
